package com.slz3.business.module.orderManagement.ordOrder.steward;

import com.slz3.business.frame.steward.FindJoinSteward;
import com.slz3.business.frame.util.VE;
import com.slz3.business.module.orderManagement.ordOrder.domain.OrdOrder;
import com.slz3.business.module.orderManagement.ordOrder.domain.OrdOrderCondition;
import com.slz3.business.module.orderManagement.ordOrder.domain.OrdOrderFactory;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.MultiValueMap;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class OrdOrderSpecification {

    public static FindJoin findJoin(MultiValueMap<String, String> params) {
        return new FindJoin(params);
    }

    private static class FindJoin implements Specification<OrdOrder> {

        private MultiValueMap<String, String> params;

        private OrdOrderCondition condition;

        public FindJoin(MultiValueMap<String, String> params) {
            this.params = params;
            this.condition = OrdOrderFactory.newConditionByMultiValueMap(params);
        }

        @Override
        public Predicate toPredicate(Root<OrdOrder> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

            final List<Predicate> predicateList = new ArrayList<>();

            predicateList.addAll(FindJoinSteward.appoint(root, cb, OrdOrder.class, params));
//            predicateList.add(cb.equal(root.get("validFlag").as(ValidFlag.class), ValidFlag.VALID));

            if (condition.getUuid() != null) {
                predicateList.add(cb.equal(root.get("uuid").as(UUID.class), condition.getUuid()));
            }

            if (VE.isNotEmpty(condition.getCreateTimeOUTSET()))
                predicateList.add(cb.greaterThanOrEqualTo(root.get("createTime"), condition.getCreateTimeOUTSET()));

            if (VE.isNotEmpty(condition.getCreateTimeFINISH()))
                predicateList.add(cb.lessThanOrEqualTo(root.get("createTime"), condition.getCreateTimeFINISH()));

            if (VE.isNotEmpty(condition.getLastModifyTimeOUTSET()))
                predicateList.add(cb.greaterThanOrEqualTo(root.get("lastModifyTime"), condition.getLastModifyTimeOUTSET()));

            if (VE.isNotEmpty(condition.getLastModifyTimeFINISH()))
                predicateList.add(cb.lessThanOrEqualTo(root.get("lastModifyTime"), condition.getLastModifyTimeFINISH()));

            if (condition.getSerTotalFeeLeft() != null) {
                predicateList.add(cb.greaterThanOrEqualTo(root.get("serTotalFee").as(Double.class), condition.getSerTotalFeeLeft().doubleValue()));
            }

            if (condition.getSerTotalFeeRight() != null) {
                predicateList.add(cb.lessThanOrEqualTo(root.get("serTotalFee").as(Double.class), condition.getSerTotalFeeRight().doubleValue()));
            }

            if (VE.isNotEmpty(condition.getOrderStatusList())) {
                CriteriaBuilder.In in = cb.in(root.get("serOrderStatus"));
                condition.getOrderStatusList().forEach(item -> in.value(item));
                predicateList.add(in);
            }
            if (VE.isNotEmpty(condition.getSerOrderTypeList())) {
                CriteriaBuilder.In in = cb.in(root.get("serOrderType"));
                condition.getSerOrderTypeList().forEach(item -> in.value(item));
                predicateList.add(in);
            }

            return predicateList.size() > 0 ? cb.and(predicateList.toArray(new Predicate[]{})) : null;

        }

    }

}
